package com.dino.manager.entities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;

import com.dino.manager.AbstractPage;
import com.dino.manager.clients.EditClient;
import com.dino.manager.home.HomePage;
import com.test.clients.dto.Client;
import com.test.clients.service.ClientsService;
import com.test.dao.SearchCriteria;
import com.test.mapper.enitites.EntityModel;
import com.test.mapper.enitites.EntityProperty;
import com.test.mapper.services.EntityService;
import com.test.utils.common.StringConstants;

public class EditEntity extends AbstractPage {

	/**
	 * Generated serial version UID.
	 */
	private static final long serialVersionUID = -8436460911067940725L;

	@SpringBean
	private ClientsService clientsService;

	@SpringBean
	private EntityService entityService;

	private final EntityModel entity;

	public EditEntity(final int clientId, final String tableName) {
		EntityModel entity = entityService.getEntityByTableName(clientId, tableName);
		if (entity == null) {
			entity = new EntityModel();
		}
		this.entity = entity;
		init();
	}

	public EditEntity() {
		this(null);
	}

	public EditEntity(final EntityModel entity) {
		if (entity == null) {
			this.entity = new EntityModel();
		} else {
			this.entity = entity;
		}
		if (this.entity.getClientId() != null && this.entity.getProperties() == null) {
			entityService.loadEntityProperties(this.entity);
		}
		init();
	}

	private void init() {
		add(new EditEntityForm("editEntityForm"));
		final List<EntityProperty> propertyList;
		if (entity.getClientId() == null) {
			propertyList = new ArrayList<EntityProperty>();
		} else {
			propertyList = new ArrayList<EntityProperty>(entity.getProperties());
		}
		final ListView<EntityProperty> properties = new ListView<EntityProperty>("properties", propertyList) {

			/**
			 * Generated serial version UID.
			 */
			private static final long serialVersionUID = 4382203743580313923L;

			@Override
			protected void populateItem(final ListItem<EntityProperty> item) {
				final EntityProperty prop = item.getModelObject();
				item.add(new Label("name", prop.getPropertyName()));
				item.add(new Label("column", prop.getColumnName()));
				item.add(new Label("type", prop.getPropertyType().name()));
				item.add(new Label("size", prop.getFieldLength() + ""));
				item.add(new Label("fk", prop.getForeignModel() == null ? StringConstants.NA : prop.getForeignModel().getEntityName()));
				item.add(new Label("fkto", prop.getForeignKeyTo() == null ? StringConstants.NA : prop.getForeignKeyTo().getPropertyName()));
				item.add(new Label("unique", prop.isUnique() ? StringConstants.Yes : StringConstants.No));
			}
		};
		add(properties);
		add(new Link<EditProperty>("addProperty") {

			/**
			 * Generated serial version UID.
			 */
			private static final long serialVersionUID = 1441661700825364494L;

			@Override
			public void onClick() {
				setResponsePage(new EditProperty(entity));
			}
			
		}.setVisible(entity.getClientId() != null).setEnabled(entity.getClientId() != null));
	}

	private class EditEntityForm extends Form<EntityModel> {

		/**
		 * Generated serial version UID.
		 */
		private static final long serialVersionUID = -1579889143739639009L;

		private final DropDownChoice<Client> clients;

		private final TextField<String> entityName;

		private final TextField<String> pkName;

		public EditEntityForm(final String id) {
			super(id);
			final List<Client> clientList;
			clients = new DropDownChoice<Client>("availableClients");
			clients.setChoiceRenderer(new ChoiceRenderer<Client>("name", "id"));
			if (entity.getClientId() != null) {
				final Client client = clientsService.getClientById(entity.getClientId());
				clientList = Collections.singletonList(client);
				clients.setModel(new Model<Client>(client));
				clients.setNullValid(false);
			} else {
				final SearchCriteria criteria = new SearchCriteria();
				clientList = new ArrayList<Client>(clientsService.searchForClients(criteria).getResultList());
				if (clientList.size() == 0) {
					// no clients, first define a client
					setResponsePage(EditClient.class);
				}
				clients.setModel(new Model<Client>());
				clients.setRequired(true);
			}
			clients.setChoices(clientList);
			add(clients);
			entityName = new TextField<String>("entityName",
					new Model<String>(entity.getEntityName() == null ? "" : entity.getEntityName()));
			add(entityName);
			pkName = new TextField<String>("pkName",
					new Model<String>(entity.getPrimaryKey() == null ? "" : entity.getPrimaryKey().getPropertyName()));
			add(pkName);
			add(new SubmitLink("cancelButton") {

				/**
				 * Generated serial version UID.
				 */
				private static final long serialVersionUID = 5429474142322762393L;

				@Override
				public void onSubmit() {
					setResponsePage(HomePage.class);
				}
			});
			add(new SubmitLink("saveButton") {

				/**
				 * Generated serial version UID.
				 */
				private static final long serialVersionUID = 4145705428472283056L;

				@Override
				public void onSubmit() {
					entity.setEntityName(entityName.getModelObject());
					if (entity.getClientId() == null || entity.getTableName() == null) {
						// new entity, add it
						entity.setClientId(clients.getModelObject().getId());
						entity.setPrimaryKey(new EntityProperty());
						entity.getPrimaryKey().setPropertyName(pkName.getModelObject());
						entityService.addEntity(entity);
					} else {
						// already exists, update it
						entity.getPrimaryKey().setPropertyName(pkName.getModelObject());
						entityService.updateEntity(entity);
					}
					setResponsePage(HomePage.class);
				}
			});
		}

	}
}
